package com.google.code.gronono.gps.ui.panels.pages;

import javax.swing.GroupLayout;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.event.TreeSelectionListener;

import com.google.code.gronono.commons.i18n.BundleKey;
import com.google.code.gronono.commons.i18n.BundleName;
import com.google.code.gronono.commons.swing.SwingUtils;
import com.google.code.gronono.gps.ui.controller.GPSController;
import com.google.code.gronono.gps.ui.panels.pages.tree.SortedFileTree;
import com.google.code.gronono.gps.ui.panels.pages.tree.SortedFileTreeRender;
import com.google.code.gronono.gps.ui.panels.pages.tree.SortedFileTreeSelectionListener;
import com.google.code.gronono.gps.ui.panels.pages.tree.TreeModelFactory;
import com.google.code.gronono.gps.ui.panels.pages.tree.TreeMouseListener;

/**
 * Panneau affichant les résultats du traitement.
 * @author Arnaud BRUNET
 */
@BundleName(value = "com.google.code.gronono.gps.gui")
public class AbstractResultPanel extends AbstractPagePanel {
	/** serialVersionUID. */
	private static final long serialVersionUID = -2611386248129486185L;

	/** Largeur préférée d'un arbre. */
	@BundleKey(value = "result.page.tree.width")
	private static int TREE_WIDTH;
	/** Hauteur préférée d'un arbre. */
	@BundleKey(value = "result.page.tree.height")
	private static int TREE_HEIGHT;

	/** L'arbre contenant les fichiers sources. */
	private JTree srcTree;
	/** Le scroll pane affichant l'arbre contenant les fichiers sources. */
	private JScrollPane scrollSrcPane;
	/** L'arbre contenant les fichiers destinations. */
	private JTree dstTree;
	/** Le scroll pane affichant l'arbre contenant les fichiers destination. */
	private JScrollPane scrollDstPane;
	/** Factory des models des arbres. */
	private final TreeModelFactory factory;

	/**
	 * Construit le panneau.
	 * @param controller Le contrôleur.
	 * @param title Le titre de la page
	 * @param description La description de la page.
	 */
	public AbstractResultPanel(final GPSController controller, final String title, final String description) {
		super(controller, title, description);
		factory = new TreeModelFactory(controller);

		initComponents();
		placeComponents();
	}

	/**
     * Initialise les différents composants.
     */
	private void initComponents() {
		// Création et gestion du tooltip
		srcTree = new SortedFileTree(super.getController().getConfiguration(), true);
		ToolTipManager.sharedInstance().registerComponent(srcTree);
		dstTree = new SortedFileTree(super.getController().getConfiguration(), false);
		ToolTipManager.sharedInstance().registerComponent(dstTree);

		// Gestion du contenu des arbres (model)
		srcTree.setModel(factory.createSrcModel());
		dstTree.setModel(factory.createDstModel());

		// Gestion de l'affichage (renderer)
		final SortedFileTreeRender render = new SortedFileTreeRender(dstTree);
		srcTree.setCellRenderer(render);
		dstTree.setCellRenderer(render);

		// Crée les panneaux incluant les arbres
		scrollSrcPane = new JScrollPane(srcTree);
		scrollDstPane = new JScrollPane(dstTree);

		// Gestion de la sélection
		final TreeSelectionListener sortedFileTreeSelectionListener = new SortedFileTreeSelectionListener(srcTree, dstTree);
		srcTree.getSelectionModel().addTreeSelectionListener(sortedFileTreeSelectionListener);
		dstTree.getSelectionModel().addTreeSelectionListener(sortedFileTreeSelectionListener);

		// Gestion de la souris
		srcTree.addMouseListener(new TreeMouseListener(true));
		dstTree.addMouseListener(new TreeMouseListener(false));
	}

	/**
     * Place les composants dans le panneau.
     */
	private void placeComponents() {
		final GroupLayout layout = new GroupLayout(this);
		this.setLayout(layout);

		// Horizontalement
		layout.setHorizontalGroup(
				layout.createParallelGroup()
					.addGroup(layout.createSequentialGroup()
							.addComponent(scrollSrcPane, GroupLayout.PREFERRED_SIZE, TREE_WIDTH, Short.MAX_VALUE)
							 .addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(scrollDstPane, GroupLayout.PREFERRED_SIZE, TREE_WIDTH, Short.MAX_VALUE))
	        );
		// Verticalement
		layout.setVerticalGroup(
				layout.createParallelGroup()
					.addGroup(layout.createSequentialGroup()
							.addContainerGap()
							.addGroup(layout.createParallelGroup()
									.addComponent(scrollSrcPane, GroupLayout.PREFERRED_SIZE, TREE_HEIGHT, Short.MAX_VALUE)
									.addComponent(scrollDstPane, GroupLayout.PREFERRED_SIZE, TREE_HEIGHT, Short.MAX_VALUE))
							.addContainerGap()));
	}

	/**
	 * Méthode permettant de rafraichir les arbres.
	 */
	public void refresh() {
		srcTree.setModel(factory.createSrcModel());
		dstTree.setModel(factory.createDstModel());
		SwingUtils.expandAll(srcTree);
		SwingUtils.expandAll(dstTree);
	}

}
